home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi Informant Complete 1995 - 2000
/
Delphi Informant Complete 1995 to 2000.iso
/
Delphi Informant Magazine Complete Works SOURCE CODE 1998.rar
/
1998
/
Jul
/
di9807jp
/
SFTPCLIENT
/
CDataThrd.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-02-20
|
4KB
|
171 lines
(*
Data Thread unit developed for Delphi Informant article by John Penman, January 1998
SFTP Client data thread
*)
unit CDataThrd;
interface
uses
Classes, Windows, Winsock2;
type
TDataThrd = class(TThread)
private
{ Private declarations }
protected
sktListenData,
sktData : TSocket;
DataAddr : TSockAddrIn;
Msg,
NewFileName : String;
procedure Execute; override;
procedure OnDataThrdDone(Sender : TObject);
procedure GetFile;
procedure Update;
public
constructor Create(PortNo : Integer; FileName : String);
end;
var
thrdData : TDataThrd;
implementation
uses
Dialogs, Main, CMsgThrd, SysUtils;
{ TDataThrd }
constructor TDataThrd.Create(PortNo : Integer; FileName : String);
var
Res : Integer;
begin
// create thread in suspended state, so we can set important variables ...
inherited create(TRUE);
FreeOnTerminate := TRUE;
OnTerminate := OnDataThrdDone;
sktListenData := WSASocket(AF_INET,SOCK_STREAM, IPPROTO_TCP, NIL, 0, 0);
if sktListenData = INVALID_SOCKET then
begin
Msg := Concat('Failed to create listening socket! Error ',IntToStr(WSAGetLastError));
Synchronize(Update);
State := stError;
Exit;
end;
with DataAddr do
begin
sin_port := htons(PortNo);
sin_family := AF_INET;
sin_addr.s_addr := INADDR_ANY;
end;
Res := bind(sktListenData, DataAddr, SizeOf(DataAddr));
if Res = SOCKET_ERROR then
begin
Msg := Concat('Failed to create listening socket! Error ',IntToStr(WSAGetLastError));
Synchronize(Update);
State := stError;
closesocket(sktListenData);
Exit;
end;
NewFileName := FileName;
// Start the data thread
Resume;
end;
// Execute the data transfer in the background ...
procedure TDataThrd.Execute;
begin
GetFile;
end;
// Retrieve the file ...
procedure TDataThrd.GetFile;
var
Buffers : array[0..MAXGETHOSTSTRUCT-1] of char;
Done : Boolean;
Data : PWSABUF;
Flags,
NoBytesRecv,
Res,
Size : Integer;
FileStream : TFileStream;
begin
Res := listen(sktListenData,1);
if Res = SOCKET_ERROR then
begin
Msg := Concat('Call to listen failed. Error ',IntToStr(WSAGetLastError));
Synchronize(Update);
closesocket(sktListenData);
State := stError;
Exit;
end;
Size := SizeOf(DataAddr);
sktData := WSASocket(AF_INET,SOCK_STREAM, IPPROTO_TCP, NIL, 0, 0);
sktData := accept(sktListenData, DataAddr, Size);
if sktData = INVALID_SOCKET then
begin
Msg := Concat('Call to accept failed. Error ',IntToStr(WSAGetLastError));
Synchronize(Update);
State := stError;
closesocket(sktListenData);
closesocket(sktData);
Exit;
end;
closesocket(sktListenData);
// Set the Data buffer and FileStream to avoid warning messages from the compiler
Data := NIL;
FileStream := NIL;
try
Data := AllocMem(SizeOf(Buffers));
Data.buf := Buffers;
Data.len := SizeOf(Buffers);
Flags := 0;
// Create a new file for writing
try
FileStream := TFileStream.Create('C:\'+NewFileName, fmOpenWrite);
Done := FALSE;
repeat
Res := WSARecv(sktData, Data, 1, @NoBytesRecv, @Flags, NIL, NIL);
if Res = SOCKET_ERROR then
begin
FileStream.Free;
Msg := Concat('Call to WSARecv failed. Error ',IntToStr(WSAGetLastError));
Synchronize(Update);
State := stError;
closesocket(sktData);
Exit;
end;
if NoBytesRecv = 0 then
Done := TRUE
else
FileStream.Write(Data.Buf^, NoBytesRecv);
until Done;
closesocket(sktData);
Msg := Concat('Finished downloading ', NewFileName,' .');
Synchronize(Update);
finally
FileStream.Free;
end;
finally
FreeMem(Data, SizeOf(Buffers)-1);
end;
end;
procedure TDataThrd.Update;
begin
frmMain.memStatusMsg.Lines.Add(Msg);
end;
procedure TDataThrd.OnDataThrdDone(Sender : TObject);
begin
Terminate;
Msg := 'Finished!';
Synchronize(Update);
frmMain.bbtnGetFile.Enabled := TRUE;
end;
end.